﻿using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace Core
{
    public static partial class Utils
    {
        public static class File
        {
            /// <summary>
            /// 获取文件的大小
            /// </summary>
            /// <param name="file"></param>
            /// <returns></returns>
            public static long ToSize(string file)
            {
                try
                {
                    if (System.IO.File.Exists(file) == false)
                    {
                        return 0;
                    }

                    FileInfo fileInfo = new(file);
                    return fileInfo.Length;
                }
                catch (Exception ex)
                {
                    throw new Exception("ToSize() fail, error:" + ex.Message);
                }
            }

            /// <summary>
            /// 清空文件夹
            /// </summary>
            /// <param name="path"></param>
            public static void DeleteDir(string path)
            {
                try
                {
                    if (Directory.Exists(path) == false)
                    {
                        Directory.CreateDirectory(path);
                        return;
                    }

                    DirectoryInfo dir = new(path);
                    FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //返回目录中所有文件和子目录
                    foreach (FileSystemInfo i in fileinfo)
                    {
                        if (i is DirectoryInfo) //判断是否文件夹
                        {
                            DirectoryInfo subdir = new(i.FullName);
                            subdir.Delete(true); //删除子目录和文件
                        }
                        else
                        {
                            System.IO.File.Delete(i.FullName); //删除指定文件
                        }
                    }
                }
                catch (Exception e)
                {
                    throw e;
                }
            }

            /// <summary>
            /// 删除文件
            /// </summary>
            /// <param name="path"></param>
            public static void Delete(string path)
            {
                try
                {
                    if (System.IO.File.Exists(path))
                    {
                        FileInfo fileInfo = new(path);
                        fileInfo.Delete();
                    }
                }
                catch (Exception e)
                {
                    throw e;
                }
            }


            /// <summary>
            /// 获取该目录下的所有文件，包括所有层级的子目录
            /// </summary>
            /// <param name="path"></param>
            /// <param name="pattern"></param>
            /// <param name="ignoredirstartwithstr"></param>
            public static List<string> GetFiles(string path, string pattern = "*.*", string ignoredirstartwithstr = "")
            {
                var files = new List<string>();
                if (Directory.Exists(path) == false)
                {
                    return files;
                }

                files.Clear();
                DirectoryInfo dir = new(path);
                if (ignoredirstartwithstr.Length > 0 && dir.Name.StartsWith(ignoredirstartwithstr))
                {
                    return files;
                }

                GetAllFiles(dir, ref files, pattern, ignoredirstartwithstr);

                return files;
            }

            /// <summary>
            /// 获取多个目录下的所有文件，包括所有层级的子目录
            /// </summary>
            /// <param name="path"></param>
            /// <param name="files"></param>
            /// <param name="pattern"></param>
            /// <param name="ignoredirstartwithstr"></param>
            public static void GetFiles(string[] path, string pattern, string ignoredirstartwithstr = "")
            {
                var files = new List<string>();

                for (int i = 0; i < path.Length; ++i)
                {
                    if (Directory.Exists(path[i]) == false)
                    {
                        continue;
                    }

                    DirectoryInfo dir = new(path[i]);
                    if (ignoredirstartwithstr.Length > 0 && dir.Name.StartsWith(ignoredirstartwithstr))
                    {
                        continue;
                    }

                    GetAllFiles(dir, ref files, pattern, ignoredirstartwithstr);
                }
            }

            private static void GetAllFiles(DirectoryInfo dir, ref List<string> files, string pattern,
                string ignoredirstartwithstr = "")
            {
                foreach (var f in dir.GetFiles(pattern))
                {
                    files.Add(f.FullName.Replace('\\', '/'));
                }

                foreach (var d in dir.GetDirectories())
                {
                    if (ignoredirstartwithstr.Length > 0 && d.Name.StartsWith(ignoredirstartwithstr))
                    {
                        continue;
                    }

                    GetAllFiles(d, ref files, pattern, ignoredirstartwithstr);
                }
            }

            /// <summary>
            /// 文件重命名
            /// </summary>
            /// <param name="srcname"></param>
            /// <param name="tgtname"></param>
            /// <returns></returns>
            public static bool Rename(string srcname, string tgtname)
            {
                if (System.IO.File.Exists(srcname))
                {
                    FileInfo fileInfo = new(srcname);
                    fileInfo.MoveTo(tgtname);
                    return true;
                }

                if (Directory.Exists(srcname))
                {
                    DirectoryInfo dir = new DirectoryInfo(srcname);
                    try
                    {
                        dir.MoveTo(tgtname);
                    }
                    catch (Exception ex)
                    {
                        Debug.LogError(ex.ToString());
                    }

                    return true;
                }

                return false;
            }

            /// <summary>
            /// 复制文件夹及文件
            /// </summary>
            /// <param name="sourceFolder">原文件路径</param>
            /// <param name="destFolder">目标文件路径</param>
            /// <returns></returns>
            public static void CopyFolder(string sourceFolder, string destFolder)
            {
                try
                {
                    if (Directory.Exists(sourceFolder) == false) return;

                    if (Directory.Exists(destFolder) == false)
                    {
                        Directory.CreateDirectory(destFolder);
                    }

                    //得到原文件根目录下的所有文件
                    var sourceFiles = Directory.GetFiles(sourceFolder);
                    var destFiles = Directory.GetFiles(destFolder);

                    foreach (var sourceFile in sourceFiles)
                    {
                        var fileName = Path.GetFileName(sourceFile);
                        var destFile = Path.Combine(destFolder, fileName);
                        System.IO.File.Copy(sourceFile, destFile, true); //复制文件
                    }

                    // 删除目标文件夹中源文件夹不存在的文件
                    foreach (var destFile in destFiles)
                    {
                        var fileName = Path.GetFileName(destFile);
                        var sourceFile = Path.Combine(sourceFolder, fileName);
                        if (!System.IO.File.Exists(sourceFile))
                        {
                            System.IO.File.Delete(destFile);
                        }
                    }

                    //得到原文件根目录下的所有文件夹
                    var sourceSubFolders = Directory.GetDirectories(sourceFolder);
                    var destSubFolders = Directory.GetDirectories(destFolder);

                    foreach (var sourceSubFolder in sourceSubFolders)
                    {
                        var folderName = Path.GetFileName(sourceSubFolder);
                        var destSubFolder = Path.Combine(destFolder, folderName);
                        CopyFolder(sourceSubFolder, destSubFolder); //构建目标路径,递归复制文件
                    }

                    // 删除目标文件夹中源文件夹不存在的子文件夹
                    foreach (var destSubFolder in destSubFolders)
                    {
                        var folderName = Path.GetFileName(destSubFolder);
                        var sourceSubFolder = Path.Combine(sourceFolder, folderName);
                        if (!Directory.Exists(sourceSubFolder))
                        {
                            Directory.Delete(destSubFolder, true);
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new Exception("CopyFolder() fail, error:" + e.Message);
                }
            }

            public static bool CreateFile(string filePath)
            {
                if (System.IO.File.Exists(filePath)) return false;

                try
                {
                    var directoryPath = Path.GetDirectoryName(filePath);
                    CreateDirectory(directoryPath);
                    using (System.IO.File.Create(filePath))
                    {
                        return true;
                    }
                }
                catch (Exception e)
                {
                    log.err(e);
                }

                return false;
            }

            public static bool CreateDirectoryByFilePath(string filePath)
            {
                var directoryPath = Path.GetDirectoryName(filePath);
                return CreateDirectory(directoryPath);
            }

            public static bool CreateDirectory(string directoryPath)
            {
                try
                {
                    if (string.IsNullOrWhiteSpace(directoryPath))
                    {
                        directoryPath = Directory.GetCurrentDirectory();
                    }

                    if (!Directory.Exists(directoryPath))
                    {
                        Directory.CreateDirectory(directoryPath);
                        return true;
                    }
                }
                catch (Exception e)
                {
                    log.err(e);
                }

                return false;
            }

            public static bool CheckFolderIsEmpty(string folderPath)
            {
                // 检查文件夹是否存在
                if (!Directory.Exists(folderPath))
                {
                    Debug.LogError("指定的文件夹不存在: " + folderPath);
                    return true;
                }

                // 获取文件夹下的所有文件和子文件夹
                string[] files = Directory.GetFiles(folderPath);
                string[] directories = Directory.GetDirectories(folderPath);

                // 如果文件数组或子文件夹数组的长度大于0，则说明文件夹下有内容
                return files.Length <= 0 && directories.Length <= 0;
            }

            public static string GetRegularPath(string path)
            {
                return path?.Replace('\\', '/');
            }
        }
    }
}